﻿#include "util.h"

#include <QDebug>
#include <QDir>
#include <QFileInfo>
#include <QUuid>
#include <QDateTime>
#include <QCryptographicHash>
#include <QDesktopWidget>
#include <QApplication>
#include <QRegExp>
#include <QDomDocument>
#include <QDomElement>
#include <QProcess>

namespace Common {

	/**
	 * @brief Uuid
	 * @note  鍦ㄤ竴瀹氱殑鑼冨洿鍐咃紙浠庣壒瀹氱殑鍚嶅瓧绌洪棿鍒板叏鐞冿級鍞竴鐨勬満鍣ㄧ敓鎴愮殑鏍囪瘑绗?
	 * @return
	 */
	QString Util::RgUUID()
	{
		QString uuid = QUuid::createUuid().toString();
		uuid.replace(QRegExp("\\W+"), "");
		return uuid;
	}

	QString Util::UUID()
	{
		QString t_strUuId;
		QUuid id = QUuid::createUuid();
		t_strUuId = id.toString();
		t_strUuId.remove("{").remove("}");
		return t_strUuId;
	}


	/********************************************************************************/

	QString Util::swithIntToIp(int value, bool reverse)
	{
		if (reverse)
			return QString("%1.%2.%3.%4").arg(value & 0xFF).arg((value >> 8) & 0xFF).arg((value >> 16) & 0xFF).arg((value >> 24) & 0xFF);
		else
			return QString("%1.%2.%3.%4").arg((value >> 24) & 0xFF).arg((value >> 16) & 0xFF).arg((value >> 8) & 0xFF).arg(value & 0xFF);
	}

	QString Util::swithLongToMac(long value)
	{
		QStringList list;
		for (int i = 0; i < 6; i++) {
			list.append(QString::number(value >> (8 * i), 16));
		}
		return list.join(":");
	}

	/**
	 * @brief Util::swithIpv4StringToInteger
	 * @param ip
	 * @return
	 */
	quint32 Util::swithIpv4StringToInteger(const QString &ip)
	{
		QStringList t_ips = ip.split(".");
		if (t_ips.size() == 4) {
			QString t_ip1 = t_ips.at(3);
			QString t_ip2 = t_ips.at(2);
			QString t_ip3 = t_ips.at(1);
			QString t_ip4 = t_ips.at(0);
			return t_ip1.toInt() | t_ip2.toInt() << 8 | t_ip3.toInt() << 16 | t_ip4.toInt() << 24;
		}
		return 0;
	}

	/*!
	 * @brief 灏嗚秴闀跨殑瀛楃涓茶浆鎹互...缁撳熬鐨勫瓧绗?
	 * @param[in] font 甯︽樉绀哄尯瀛椾綋
	 * @param[in] origin 鍘熷鏄剧ず鍐呭
	 * @param[in] maxLen 鏈€澶ф樉绀哄搴?
	 * @return 杞崲鍚庣殑瀛楃
	 */
	QString Util::replaceLongTextWidthElide(const QFont &font, const QString &origin, const int maxLen)
	{
		QString str;
		QFontMetrics fontWidth(font);
		if (fontWidth.width(origin) >= maxLen)
			str = fontWidth.elidedText(origin, Qt::ElideRight, maxLen);
		else
			str = origin;
		return str;
	}

	QSize Util::screenSize(int num)
	{
		if (num >= 0 && num < qApp->desktop()->screenCount()) {
			return qApp->desktop()->screen(num)->size();
		}
		return qApp->desktop()->screen()->size();
	}

	/*!
	 * @brief 鑾峰彇灞忓箷鍧愭爣灏哄鑼冨洿
	 * @details 鍦ㄥ绐楀彛涓嬶紝涓诲睆鍜屽壇灞忔湁椤哄簭鍏崇郴銆傞『搴忎笉鍚岋紝鍏跺潗鏍囩殑鑼冨洿瀛樺湪宸紓 @n
	 *          鑻涓轰富灞忋€丅涓鸿緟灞忥紝閭ｄ箞AB鎺掑垪鏃讹紝鍧愭爣鑼冨洿涓篬0,2W][0,H] @n
	 *          鑻A鎺掑垪鏃讹紝鍧愭爣鑼冨洿鏄痆-W,W][0,H] @n
	 * @warning AB銆丅A鎺掑垪鏃跺湪鑾峰彇鎺т欢鐨勪綅缃椂鏈夎緝澶х殑褰卞搷銆?
	 * @param[in] 鏃?
	 * @return 灞忓箷鍧愭爣
	 */
	QRect Util::screenGeometry()
	{
		int screenSize = qApp->desktop()->screenCount();

		int minX = 0, maxX = 0, minY = 0, maxY = 0;
		for (int i = 0; i < screenSize; i++)
		{
			QRect tmpRect = qApp->desktop()->screenGeometry(i);
			minX = tmpRect.x() < minX ? tmpRect.x() : minX;
			maxX = tmpRect.x() + tmpRect.width() > maxX ? tmpRect.x() + tmpRect.width() : maxX;
			minY = tmpRect.y() < minY ? tmpRect.y() : minY;
			maxY = tmpRect.y() + tmpRect.height() > maxY ? tmpRect.y() + tmpRect.height() : maxY;
		}

		QRect rect;
		rect.setLeft(minX);
		rect.setRight(maxX);
		rect.setTop(minY);
		rect.setBottom(maxY);

		return rect;
	}

	QRect Util::centerScreen(QSize &widgetSize)
	{
		QSize screen = screenSize();
		return QRect(QPoint((screen.width() - widgetSize.width()) / 2,
			(screen.height() - widgetSize.height()) / 2), widgetSize);

	}

	bool Util::validateIpFormat(QString dest)
	{
		QString matchIp = "(\\d|([1-9]\\d)|(1\\d{2})|(2[0-4]\\d)|(25[0-5]))";
		QString matchWholeIp = QString("(%1\\.){3}%2").arg(matchIp).arg(matchIp);
		QRegExp rx(matchWholeIp);

		return rx.exactMatch(dest);
	}

	/*!
	 * @brief 灏嗗浘鐗囪浆鎹㈡垚鐏板害鍥?
	 * @param[in] image锛歝onst QImage &锛岃浆鎹㈠墠鐨勫浘鐗?
	 * @return 鏃?t_grayImage锛歈Image锛岃浆鎹㈠悗鐨勭伆搴﹀浘
	 */
	QImage Util::convertToGray(const QImage &t_image)
	{
		int t_height = t_image.height();
		int t_width = t_image.width();
		QImage t_grayImage(t_width, t_height, QImage::Format_Indexed8);
		t_grayImage.setColorCount(256);
		for (int i = 0; i < 256; i++)
		{
			t_grayImage.setColor(i, qRgb(i, i, i));
		}
		switch (t_image.format())
		{
		case QImage::Format_Indexed8:
			for (int i = 0; i < t_height; i++)
			{
				const unsigned char *pSrc = (unsigned char *)t_image.constScanLine(i);
				unsigned char *pDest = (unsigned char *)t_grayImage.scanLine(i);
				memcpy(pDest, pSrc, t_width);
			}
			break;
		case QImage::Format_RGB32:
		case QImage::Format_ARGB32:
		case QImage::Format_ARGB32_Premultiplied:
			for (int i = 0; i < t_height; i++)
			{
				const QRgb *pSrc = (QRgb *)t_image.constScanLine(i);
				unsigned char *pDest = (unsigned char *)t_grayImage.scanLine(i);

				for (int j = 0; j < t_width; j++)
				{
					pDest[j] = qGray(pSrc[j]);
				}
			}
			break;
		default:
			break;
		}
		return t_grayImage;
	}

	/*!
	 * @brief 灏嗗瓧绗︿覆杞崲涓哄彲鏄剧ず鐨凥TML婧愮爜
	 * @param targetHtml 闇€瑕佽浆涔夊鐞嗙殑瀛楃涓?
	 */
	void Util::StringToHtml(QString &targetHtml)
	{
		escapeSingleQuote(targetHtml);
		escapeBracketsQuote(targetHtml);
		escapeLFQuote(targetHtml);
	}

	/*!
	 * @brief RUtil::escapeQuote 灏咹tml鍐呭涓殑鍙屽紩鍙枫€佸崟寮曞彿杩涜杞箟
	 * @param targetHtml 闇€瑕佽浆涔夊鐞嗙殑Html鍐呭
	 */
	void Util::escapeSingleQuote(QString &targetHtml)
	{
		targetHtml = targetHtml.replace("\\", "\\\\");
		targetHtml = targetHtml.replace("\'", "&qpos");
	}

	void Util::escapeBracketsQuote(QString &targetHtml)
	{
		targetHtml = targetHtml.replace("<", "&lt;");
		targetHtml = targetHtml.replace("<=", "&le;");
		targetHtml = targetHtml.replace(">", "&gt;");
		targetHtml = targetHtml.replace(">=", "&ge;");
	}

	/*!
	 * @brief 杞崲鍥炶溅绗﹀彿涓篐TML鍙樉绀哄瓧绗?
	 * @param targetHtml 婧愬瓧绗︿覆
	 */
	void Util::escapeLFQuote(QString &targetHtml)
	{
		targetHtml = targetHtml.replace("\n", "</br>");
		targetHtml = targetHtml.replace(" ", "&nbsp;");
	}

	/*!
	 * @brief RUtil::removeEccapeQuote 绉婚櫎Html鍐呭涓弻寮曞彿鐨勮浆涔夌鍙?
	 * @param targetHtml 闇€瑕佺Щ闄よ浆涔夊鐞嗙殑Html鍐呭
	 */
	void Util::removeEccapeSingleQuote(QString &targetHtml)
	{
		targetHtml = targetHtml.replace("\\\'", "\'");
		targetHtml = targetHtml.replace("\n", "");
	}

	void Util::escapeDoubleQuote(QString &targetHtml)
	{
		targetHtml = targetHtml.replace("\"", "\\\"");
		targetHtml = targetHtml.replace("\n", "");
	}

	/*!
	 * @brief RUtil::removeEccapeDoubleQuote
	 * @param targetHtml
	 */
	void Util::removeEccapeDoubleQuote(QString &targetHtml)
	{
		targetHtml = targetHtml.replace("\\\"", "\"");
		targetHtml = targetHtml.replace("\n", "");
	}

	/*!
	 * @brief 鍦‥xplorer涓樉绀?
	 * @param path 寰呮樉绀鸿矾寰?
	 */
	void Util::showInExplorer(QString &pathIn)
	{
		QString explorer = QLatin1String("explorer.exe");
		QMap<QString, QString> m_values;
		QString explorerPath;

		QStringList env = QProcessEnvironment::systemEnvironment().toStringList();
		foreach(const QString &s, env) {
			int i = s.indexOf(QLatin1Char('='));
			if (i >= 0) {
				m_values.insert(s.left(i).toUpper(), s.mid(i + 1));
			}
		}

		QString exec = QDir::cleanPath(explorer);

		QStringList pathEnv = m_values.value(QLatin1String("PATH")).split(QLatin1Char(';'),
			QString::SkipEmptyParts);
		foreach(const QString &p, pathEnv) {
			QString directory = QDir::fromNativeSeparators(p);
			const QChar slash = QLatin1Char('/');
			if (!directory.endsWith(slash))
				directory += slash;
			QFileInfo fi(directory + exec);
			if (fi.exists() && fi.isFile() && fi.isExecutable()) {
				explorerPath = fi.absoluteFilePath();
				break;
			}
		}
		if (explorerPath.isEmpty())
			return;
		QStringList param;
		if (!QFileInfo(pathIn).isDir())
			param += QLatin1String("/select,");
		param += QDir::toNativeSeparators(pathIn);
		QProcess::startDetached(explorerPath, param);
	}

	/*!
	 * @brief 鏍煎紡鍖栨樉绀烘枃浠跺ぇ灏?
	 * @param byteSize 鏂囦欢澶у皬锛屽崟浣嶅瓧鑺?
	 * @return 鏄剧ず鐨勬枃浠跺ぇ灏?
	 */
	QString Util::formatFileSize(int byteSize)
	{
		QString t_fileSize = QString();
		if (byteSize < 1024) {
			QString t_showSize = QString::number(byteSize, 'f', 2);
			t_fileSize = QString("(%1B)").arg(t_showSize);
		}
		else if (byteSize >= 1024 && byteSize < 1024 * 1024) {
			QString t_showSize = QString::number(byteSize / 1024, 'f', 2);
			t_fileSize = QString("(%1KB)").arg(t_showSize);
		}
		else if (byteSize >= 1024 * 1024) {
			QString t_showSize = QString::number(byteSize / (1024 * 1024), 'f', 2);
			t_fileSize = QString("(%1MB)").arg(t_showSize);
		}
		return t_fileSize;
	}

}//namespace Core
